package utils

import (
	crand "crypto/rand"
	"encoding/binary"
	"fmt"
	mrand "math/rand"
	"sync"
	"time"
)

var r *mrand.Rand = NewTrueScopeRand()
var rPool *sync.Pool

func init() {
	rPool = &sync.Pool{New: func() interface{} {
		return NewTrueScopeRand()
	}}
}

// TrueScopeRand 真随机数，范围随机,min<= V <max
func TrueScopeRand(min int64, max int64) int64 {
	//fmt.Printf("xxx %d-%d\n", min, max)
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("xxx %d-%d\n", min, max)
			fmt.Printf("err %s\n", err)
		}
	}()
	tmp := rPool.Get().(*mrand.Rand)
	defer rPool.Put(tmp) //用完放回去
	return tmp.Int63n(max-min) + min
}

// TrueScopeRandNoSafe 真随机数(非并发安全)
// 全局使用一个rand的情况下会引发数组panic（未知原因）
func TrueScopeRandNoSafe(min int64, max int64) int64 {
	return r.Int63n(max-min) + min
}

func NewTrueScopeRand() *mrand.Rand {
	var seed int64
	binary.Read(crand.Reader, binary.BigEndian, &seed)
	return mrand.New(mrand.NewSource(seed * time.Now().UnixNano()))
}
